﻿using System.IO;
using System.Linq;
using System.Net;
using NUnit.Framework;
using System;
using System.Xml;
using System.Threading;

namespace Twitter.Tests
{
	[TestFixture]
	public class MessagesFixture : TestBase
	{
		[ExpectedException(typeof(ArgumentNullException))]
		[Test]
		public void ShouldThrowIfNullSendMessageUser()
		{
			TestRun.CreateClient().Messages.Send(null, "foo");
		}

		[ExpectedException(typeof(ArgumentException))]
		[Test]
		public void ShouldThrowIfEmptySendMessageUser()
		{
			TestRun.CreateClient().Messages.Send("", "foo");
		}

		[ExpectedException(typeof(ArgumentNullException))]
		[Test]
		public void ShouldThrowIfNullSendMessageMessage()
		{
			TestRun.CreateClient().Messages.Send("foo", null);
		}

		[ExpectedException(typeof(ArgumentException))]
		[Test]
		public void ShouldThrowIfEmptySendMessageMessage()
		{
			TestRun.CreateClient().Messages.Send("foo", "");
		}

		[ExpectedException(typeof(ArgumentNullException))]
		[Test]
		public void ShouldThrowIfNullDeleteMessageId()
		{
			TestRun.CreateClient().Messages.Delete(null);
		}

		[ExpectedException(typeof(ArgumentException))]
		[Test]
		public void ShouldThrowIfEmptyDeleteMessageId()
		{
			TestRun.CreateClient().Messages.Delete("");
		}

		[Test]
		public void ShouldSendAndGetNewMessage()
		{
			IBotClient bot;
			IBotClient client;
			TestRun.CreateClients(out bot, out client);

			bot.Friendship.Follow(TestRun.ClientScreenName);
			client.Friendship.Follow(TestRun.BotScreenName);

			try
			{
				Message sent = client.Messages.Send(TestRun.BotScreenName, "Foo");

				Assert.IsNotNull(sent);
				Assert.AreEqual(TestRun.BotScreenName, sent.Recipient.ScreenName);
				Assert.AreEqual(TestRun.ClientScreenName, sent.Sender.ScreenName);

				var received = bot.Messages.GetAll().LastOrDefault();

				Assert.IsNotNull(received);
				Assert.AreEqual(sent.Id, received.Id);
				Assert.AreEqual(sent.Created, received.Created);
				Assert.AreEqual(sent.Recipient.ScreenName, received.Recipient.ScreenName);
				Assert.AreEqual(sent.Sender.ScreenName, received.Sender.ScreenName);
				Assert.AreEqual(sent.Text, received.Text);

			}
			finally
			{
				bot.Friendship.Leave(TestRun.ClientScreenName);
				client.Friendship.Leave(TestRun.BotScreenName);
			}
		}

		[Test]
		public void ShouldDeleteMessageById()
		{
			IBotClient bot;
			IBotClient client;
			TestRun.CreateClients(out bot, out client);

			bot.Friendship.Follow(TestRun.ClientScreenName);
			client.Friendship.Follow(TestRun.BotScreenName);

			try
			{
				Message sent = client.Messages.Send(TestRun.BotScreenName, "Foo");

				Assert.AreEqual(1, bot.Messages.GetAll().Count());

				bot.Messages.Delete(sent.Id);

				Assert.AreEqual(0, bot.Messages.GetAll().Count());

			}
			finally
			{
				bot.Friendship.Leave(TestRun.ClientScreenName);
				client.Friendship.Leave(TestRun.BotScreenName);
			}
		}

		[Test]
		public void ShouldGetAllMessages()
		{
			IBotClient bot;
			IBotClient client;
			TestRun.CreateClients(out bot, out client);

			bot.Friendship.Follow(TestRun.ClientScreenName);
			client.Friendship.Follow(TestRun.BotScreenName);

			try
			{
				client.Messages.Send(TestRun.BotScreenName, "Foo");
				Thread.Sleep(100);
				while (bot.Messages.GetLatest().Text != "Foo")
					Thread.Sleep(100);

				client.Messages.Send(TestRun.BotScreenName, "Bar");
				Thread.Sleep(100);
				while (bot.Messages.GetLatest().Text != "Bar")
					Thread.Sleep(100);

				client.Messages.Send(TestRun.BotScreenName, "Baz");
				Thread.Sleep(100);
				while (bot.Messages.GetLatest().Text != "Baz")
					Thread.Sleep(100);

				var msgs = bot.Messages.GetAll().Reverse().ToList();

				Assert.AreEqual("Baz", msgs[0].Text);
				Assert.AreEqual("Bar", msgs[1].Text);
				Assert.AreEqual("Foo", msgs[2].Text);
			}
			finally
			{
				bot.Friendship.Leave(TestRun.ClientScreenName);
				client.Friendship.Leave(TestRun.BotScreenName);
			}
		}
	}
}
